package com.excilys.formation.project.services;

import java.util.List;
import java.util.Map;

import javax.validation.constraints.Min;

import org.joda.time.Interval;
import org.joda.time.YearMonth;

import com.excilys.formation.project.entities.Operation;
import com.excilys.formation.project.entities.TypeOperation;

/**
 * Service de gestion des opérations.
 * 
 * @author excilys
 * 
 */
public interface OperationService {
	/**
	 * @param compteNumero
	 *            Le numéro du compte sur lequel porte la recherche
	 * @param mois
	 *            Le mois de l'année.
	 * @return Les opérations pour un compte d'un mois donné triées par date.
	 */
	List<Operation> getOperationsByCompteByYearMonth(String compteNumero, YearMonth mois);

	/**
	 * 
	 * @param compteNumero
	 *            Le numéro du compte sur lequel porte la recherche
	 * @param mois
	 *            Le mois de l'année.
	 * @param type
	 *            Le type d'opérations
	 * @param offset
	 *            numéro du premier résultat à récupérer
	 * @param limit
	 *            nombre de résultat à récupérer
	 * @return Les opérations d'un certain type pour un compte d'un mois donné triées par date.
	 */
	List<Operation> getOperationsByCompteByYearMonthAndType(String compteNumero, YearMonth mois, TypeOperation type, @Min(0) int offset,
			@Min(0) int limit);

	/**
	 * Renvoie les opérations d'un compte donné dans un interval de temps à l'exception des opérations d'un certain type.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param mois
	 *            Le mois de l'année.
	 * @param type
	 *            Type d'opérations à exclure
	 * @param offset
	 *            numéro du premier résultat à récupérer
	 * @param limit
	 *            nombre de résultat à récupérer
	 * @return les opérations d'un compte donné.
	 */
	List<Operation> getOperationsByCompteByYearMonthExceptType(String compteNumero, YearMonth mois, TypeOperation type, @Min(0) int offset,
			@Min(0) int limit);

	/**
	 * Renvoie la somme du montant des opérations d'un type donné dans un interval de temps.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut sommer les montants des opérations
	 * @param mois
	 *            Le mois de l'année.
	 * @param typeOperation
	 *            Type d'opérations dont il faut sommer les montants
	 * @return Somme des opérations du type demandé du compte, dans un mois donné.
	 */
	double getSumOperationsByCompteByYearMonthAndType(String compteNumero, YearMonth mois, TypeOperation typeOperation);

	/**
	 * Renvoie la somme du montant des encours carte, des operations de Type Carte_differé.
	 * 
	 * @param clientId
	 *            L'ID du client dont il faut sommer les montants des opérations
	 * @return Somme des Encours carte du compte.
	 */
	Map<String, Double> getSumEncoursByClient(long clientId);

	TypeOperation getTypeByID(int i);

	/**
	 * Renvoie le nombre d'opérations d'un compte donné dans un interval de temps à l'exception des opérations d'un certain type.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param type
	 *            Type d'opérations à exclure
	 * @return le nombre d'opérations d'un compte donné.
	 */
	long getCountOperationsByCompteAndTimeIntervalExceptType(String compteNumero, Interval interval, TypeOperation type);

	/**
	 * Renvoie le nombre d'opérations d'un certain type d'un compte donné dans un interval de temps.
	 * 
	 * @param compteNumero
	 *            Le numéro du compte dont il faut récupérer les opérations
	 * @param interval
	 *            Interval de dates pour récupérer les opérations
	 * @param type
	 *            Type d'opérations à récupérer
	 * @return le nombre d'opérations d'un compte donné.
	 */
	long getCountOperationsByCompteAndTimeIntervalAndType(String compteNumero, Interval interval, TypeOperation type);

}
